﻿using Signit.Sdk.Types;
using Signit.Sdk.Util;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Viyi.Util.Codec;

namespace Signit.Sdk.Http
{
    public class Authentication
    {
        private const string KeyBase64 = "9ijhWI+0fNf0RSRJxgPt7q2zciyGVxmcco95I+gKids=";

        public string AppId { get; set; } = "";
        public string SecuretKey { get; set; } = "";
        public string AccessToken { get; set; } = "";
        public TokenType AccessTokenType { get; set; } = TokenType.CLIENT_CREDENTIALS;

        // TODO private string cacheTokenDir = System.getProperty("java.io.tmpdir");
        public string CacheTokenDir = Path.GetTempPath();


        public Authentication() { }

        public Authentication(string apiKey, string secretKey, TokenType authType)
        {
            AppId = apiKey;
            SecuretKey = secretKey;
            AccessTokenType = authType;
            InitFromLocal();
        }

        public bool HasAppId => !string.IsNullOrEmpty(AppId);
        public bool HasSecretKey => !string.IsNullOrEmpty(SecuretKey);

        public bool HasAccessToken
        {
            get
            {
                InitFromLocal();
                return !string.IsNullOrEmpty(AccessToken);
            }
        }

        private void CacheToLocal()
        {
            if (!string.IsNullOrWhiteSpace(AccessToken))
            {
                return;
            }

            string filePath = GenerateCachedTokenFilename();
            if (filePath == null)
            {
                return;
            }

            try
            {
                byte[] data = Encoding.ASCII.GetBytes(AccessToken);
                byte[] secretData = data.AesEncrypt(KeyBase64);
                File.WriteAllBytes(filePath, secretData);
            }
            catch
            {
                // DO-NOTHING
                return;
            }
        }

        private void InitFromLocal()
        {
            if (!string.IsNullOrWhiteSpace(AccessToken))
            {
                return;
            }

            string filePath = GenerateCachedTokenFilename();
            if (filePath == null || !File.Exists(filePath))
            {
                return;
            }

            try
            {
                var secretData = File.ReadAllBytes(filePath);
                var data = secretData.AesDecrypt(KeyBase64);
                AccessToken = Encoding.ASCII.GetString(data);
            }
            catch
            {
                // DO-NOTHING
                return;
            }
        }

        private string GenerateCachedTokenFilename()
        {
            if (string.IsNullOrEmpty(AppId) || string.IsNullOrEmpty(SecuretKey))
            {
                return null;
            }

            var combine = string.Join(",", new[]
            {
                AppId, SecuretKey, AccessTokenType.ToString()
            });

            var hash = MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(combine));
            var filename = Path.Combine(CacheTokenDir, hash.Base64Encode());
            return filename;
        }
    }
}
